// @ts-check

/** 用于删除所有标签的內联样式 */
const AllInlineStyles =
    /<(a|img|p|b|div|span|font|h1|h2|h3|h4|h5|h6|strong|italic) (.*?)(style=('[^']*?'|"[^"]*?"))(.*?)>/g;

/**
 * 过滤指定标签的內联样式
 *
 * @param {string} rawHtml 原始 html 字符串
 * @param {string[]|string} [tagsToStrip] 需要过滤的标签数组，如果不传，则过滤所有标签的內联样式
 * @returns {string} 过滤內联样式的 html 字符串
 */
export default function stripInlineStyle(rawHtml, tagsToStrip) {
    if (!rawHtml) return '';

    // 不含标签的文本无需处理
    if (rawHtml.indexOf('<') === -1) return rawHtml;

    // 删除所有标签的內联样式
    if (!tagsToStrip || tagsToStrip.length <= 0) {
        return doStrip(rawHtml, AllInlineStyles);
    }

    // 删除指定标签的內联样式
    const normalized = normalizeTags(tagsToStrip);
    const stripReg = createRegExp(normalized);
    return doStrip(rawHtml, stripReg);
}

/**
 * 规范化标签数组
 * @param {string|string[]} tags 标签数组
 * @returns {string[]}
 */
function normalizeTags(tags) {
    let result = [];
    if (typeof tags === 'string') {
        result.push(tags);
    } else if (Array.isArray(tags)) {
        result = tags;
    } else {
        throw new Error('invalid argument, tags: ' + tags);
    }

    return result;
}

/**
 * 执行过滤內联样式的操作
 * @param {string} rawHtml 原始字符串
 * @param {RegExp} stripReg 过滤正则表达式
 * @returns {string}
 */
function doStrip(rawHtml, stripReg) {
    let result = rawHtml.replace(stripReg, '<$1 $2$5>');
    return stripBlanksBeforeGreaterThan(result);
}

/**
 * 创建动态正则表达式
 * @param {string[]} arr
 * @returns {RegExp}
 */
function createRegExp(arr) {
    const str = `<(${arr.join('|')}) (.*?)(style=('[^']*?'|"[^"]*?"))(.*?)>`;
    return new RegExp(str, 'g');
}

/**
 * 删除大于号前的空白符号
 * @param {string} rawHtml
 * @returns {string}
 */
function stripBlanksBeforeGreaterThan(rawHtml) {
    if (!rawHtml) return '';
    return rawHtml
        .replace(/<(.*?)(\s*)>/g, '<$1>') // 删除大于号前的空格
        .replace(/<(.*?)\s+\/>/g, '<$1 />'); // 将 /> 前的多个空格压缩为一个空格
}
